﻿using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Markup;
using Microsoft.Win32;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace HearthHelper
{
	public partial class MainWindow : Window
	{
		public ObservableCollection<AccountCheckedItem> AccountList = 
			new ObservableCollection<AccountCheckedItem>();
		private readonly System.Windows.Forms.Timer TimerTick = 
			new System.Windows.Forms.Timer();
		private readonly System.Windows.Forms.Timer TimerMonitor =
			new System.Windows.Forms.Timer();
		private AccountCheckedItem CurrRunningAccount =
			new AccountCheckedItem(false, "");
		private bool ForceCloseBattle = false;
		private bool IsRunning = false;
		private DateTime LastDateTime = default(DateTime);
		private int TodayRebootCnt = 0;
		private long LastPushNormalDateTime = DateTime.Now.ToBinary()/1000/10000-24*3600;
		private const int DefaultBNHSInterval = 20;
		private const int DefaultHSHBInterval = 30;
		private const int DefaultCheckInterval = 5;
		private const int DefaultRebootCntMax = 30;
		private const int DefaultSystemVersion = 0;
		private const int DefaultPushNormalInterval = 2;
		private string MyTitlt = "中控V5.2.0--[2022-06-30]--By琴弦上的宇宙";

		public MainWindow()
		{
			InitializeComponent();
		}

		[DllImport("kernel32.dll")]
		private static extern int WinExec(string exeName, int operType);

		//数据处理
		private string BaseDirectory
		{
			get{return AppDomain.CurrentDomain.BaseDirectory;}
		}
		private Process[] BattleNetUpdateAgentProcess
		{
			get{return Process.GetProcessesByName("Agent");}
		}
		private Process[] BattleNetProcess
		{
			get{return Process.GetProcessesByName("Battle.net");}
		}
		private Process[] HearthstoneProcess
		{
			get{return Process.GetProcessesByName("Hearthstone");}
		}
		private string BattleNetPath
		{
			get{return BattleNetPathTextBox.Text;}
			set{BattleNetPathTextBox.Text = value;}
		}
		private string HearthstonePath
		{
			get{return HearthstonePathTextBox.Text;}
			set{HearthstonePathTextBox.Text = value;}
		}
		private string HearthbuddyPath
		{
			get{return HearthbuddyPathTextBox.Text;}
			set{HearthbuddyPathTextBox.Text = value;}
		}
		private int BNHSInterval
		{
			get{int x; return int.TryParse(BNHSIntervalTextBox.Text,out x)?x:DefaultBNHSInterval;}
			set{BNHSIntervalTextBox.Text = value.ToString(); }
		}
		private int HSHBInterval
		{
			get{int x;return int.TryParse(HSHBIntervalTextBox.Text,out x)?x:DefaultHSHBInterval;}
			set{HSHBIntervalTextBox.Text = value.ToString(); }
		}
		private int CheckInterval
		{
			get{int x; return int.TryParse(CheckIntervalTextBox.Text,out x)?x:DefaultCheckInterval;}
			set{CheckIntervalTextBox.Text = value.ToString(); }
		}
		private bool NeedCloseBattle
		{
			get{return (bool)NeedCloseBattleCheckBox.IsChecked; }
			set{NeedCloseBattleCheckBox.IsChecked = value; }
		}
		private bool NeedMultStone
		{
			get{return (bool)NeedMultStoneCheckBox.IsChecked; }
			set{NeedMultStoneCheckBox.IsChecked = value; }
		}
		private string TodayRebootCntStr
		{
			set{TodayRebootCntLabel.Content = value; }
		}
		private int RebootCntMax
		{
			get{int x; return int.TryParse(RebootMaxCntTextBox.Text,out x)?x:DefaultCheckInterval; }
			set{RebootMaxCntTextBox.Text = value.ToString(); }
		}
		private int SystemVersion
		{
			get{return SystemVersionComboBox.SelectedIndex; }
			set{SystemVersionComboBox.SelectedIndex = value; }
		}
		private string PushPlusToken
		{
			get{return PushPlusTokenTextBox.Text; }
			set{PushPlusTokenTextBox.Text = value; }
		}
		private bool NeedPushMessage
		{
			get{return (bool)NeedPushMessageCheckBox.IsChecked; }
			set{NeedPushMessageCheckBox.IsChecked = value; }
		}
		private bool NeedPushNormal
		{
			get{return (bool)NeedPushNormalCheckBox.IsChecked; }
			set{NeedPushNormalCheckBox.IsChecked = value; }
		}
		private int PushNormalInterval
		{
			get{int x; return int.TryParse(
				 PushNormalIntervalTextBox.Text,out x)?x:DefaultPushNormalInterval; }
			set{PushNormalIntervalTextBox.Text = value.ToString(); }
		}

		//延时函数
		private static void Delay(int mm)
		{
			DateTime current = DateTime.Now;
			while (current.AddMilliseconds(mm) > DateTime.Now)
			{
				System.Windows.Forms.Application.DoEvents();
			}
		}

		//日志
		private void Log(string log)
		{
			LogTextBox.AppendText(DateTime.Now.ToLongTimeString() + "：" +
				(NeedMultStone ? "[多]" : "[单]") + log + "\n");
			LogTextBox.ScrollToEnd();
		}

		//选择文件，返回文件完整路径
		private static string SelectExeFile(string filter)
		{
			var openFileDialog = new Microsoft.Win32.OpenFileDialog()
			{
				Filter = filter,
				DereferenceLinks = false
			};
			if (openFileDialog.ShowDialog() == true)
			{
				return openFileDialog.FileName;
			}
			return string.Empty;
		}

		//自动获取战网路径
		private string AutoGetBattleNetPath()
		{
			string BattleNetPath = PathUtil.FindInstallPathFromRegistry("Battle.net");
			if (!string.IsNullOrEmpty(BattleNetPath) && Directory.Exists(BattleNetPath)
				&& File.Exists(Path.Combine(BattleNetPath, "Battle.net Launcher.exe")))
			{
				string path= Path.Combine(BattleNetPath, "Battle.net Launcher.exe");
				Log("自动获取战网路径成功：");
				Log(path);
				return path;
			}
			Log("自动获取战网路径失败，请手动选择");
			return string.Empty;
		}

		//自动获取补丁路径
		private string AutoGetHearthstonePath()
		{
			string HearthstonePath = PathUtil.FindInstallPathFromRegistry("Hearthstone");
			if (!string.IsNullOrEmpty(HearthstonePath) && Directory.Exists(HearthstonePath)
				&& File.Exists(Path.Combine(HearthstonePath, "Hearthstone.exe")))
			{
				string path = Path.Combine(HearthstonePath,
					@"Hearthstone_Data\Managed\Assembly-CSharp.dll");
				Log("自动获取补丁路径成功：");
				Log(path);
				return path;
			}
			Log("自动获取补丁路径失败，请手动选择");
			return string.Empty;
		}

		//自动获取兄弟路径
		private string AutoGetHearthBuddyPath()
		{
			string currentDirectory = Directory.GetCurrentDirectory();
			if (!string.IsNullOrEmpty(currentDirectory) && Directory.Exists(currentDirectory)
				&& File.Exists(Path.Combine(currentDirectory, "Hearthbuddy.exe")))
			{
				string path = Path.Combine(currentDirectory, "Hearthbuddy.exe");
				Log("自动获取兄弟路径成功：");
				Log(path);
				return path;
			}
			Log("自动获取兄弟路径失败，请手动选择");
			return string.Empty;
		}

		//获取战网配置文件
		private string GetBattleConfig()
		{
			string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
			if (!string.IsNullOrEmpty(folderPath) && Directory.Exists(folderPath)
				&& Directory.Exists(Path.Combine(folderPath, "Battle.net"))
				&& File.Exists(Path.Combine(folderPath, "Battle.net", "Battle.net.config")))
			{
				return Path.Combine(folderPath, "Battle.net", "Battle.net.config");
			}
			return string.Empty;
		}

		//停止战网和炉石
		private void StopHearthstone()
		{
			Log("准备停止战网、炉石、战网更新进程");
			try
			{
				//停止炉石
				Log("停止炉石中...");
				Process[] processes = HearthstoneProcess;
				if (processes != null && processes.Length > 0)
				{
					foreach (Process pro in processes)
					{
						if (NeedMultStone)
						{
							if (CurrRunningAccount.Running &&
								CurrRunningAccount.StonePid == pro.Id)
							{
								pro.Kill();
								Delay(1000);
								Log($"检测到炉石(Pid={pro.Id})已停止");
								break;
							}
						}
						else
						{
							pro.Kill();
							Delay(1000);
							Log($"检测到炉石(Pid={pro.Id})已停止");
						}
					}
				}

				//停止战网
				if (NeedCloseBattle || ForceCloseBattle)
				{
					Log("停止战网中...");
					processes = BattleNetProcess;
					if (processes != null && processes.Length > 0)
					{
						foreach (Process pro in processes)
						{
							pro.Kill();
							Delay(1000);
							Log($"检测到战网(Pid={pro.Id})已停止");
						}
					}
				}

				//停止战网更新进程
				Log("停止战网更新进程中...");
				processes = BattleNetUpdateAgentProcess;
				if (processes != null && processes.Length > 0)
				{
					foreach (Process pro in processes)
					{
						pro.Kill();
						Delay(1000);
						Log($"检测到战网更新进程(Pid={pro.Id})已停止");
					}
				}
			}
			catch { }
		}

		//启动战网和炉石
		private void StartHearthstone(AccountCheckedItem item)
		{
			if (!IsRunning) return;

			Log("准备启动炉石");
			try
			{
				//启动战网
				while (BattleNetProcess.Length < 1 && IsRunning)
				{
					Log($"未检测到战网，启动战网中...，5秒后再次检测");
					WinExec(BattleNetPath, 2);
					Delay(1000 * 5);
				}
				if (!IsRunning) return;
				foreach (Process process in BattleNetProcess)
				{
					Log($"已检测到战网(Pid={process.Id})运行中");
				}

				//启动炉石
				Log($"{BNHSInterval}秒后启动炉石");
				Delay(1000 * BNHSInterval);
				Process[] alreadyProcess = HearthstoneProcess;
				while (HearthstoneProcess.Length <= alreadyProcess.Length && IsRunning)
				{
					Log($"未检测到炉石，启动炉石中...");
					if (NeedMultStone)
					{
						Log($"先停止战网更新进程...");
						Process[] processes = BattleNetUpdateAgentProcess;
						if (processes != null && processes.Length > 0)
						{
							foreach (Process pro in processes)
							{
								pro.Kill();
								Delay(1000);
								Log($"检测到战网更新进程(Pid={pro.Id})已停止");
							}
						}
						//再次检测战网更新进程
						Log($"再次检测战网更新进程...");
						while (BattleNetUpdateAgentProcess.Length < 1 && IsRunning)
						{
							Log($"未检测到战网更新进程...，1秒后再次检测");
							Delay(1000);
						}
						Log($"检测到战网更新进程已运行，4秒后启动炉石...");
						Delay(4000);
					}
					Process[] array = BattleNetProcess;
					int i = 0;
					if (i < array.Length)
					{
						Process.Start(array[i].MainModule.FileName, "--exec=\"launch WTCG\"");
					}
					Delay(1000 * 5);
				}
				foreach (Process allPro in HearthstoneProcess)
				{
					bool flag = true;
					foreach (Process alreadyPro in alreadyProcess)
					{
						if (allPro.Id == alreadyPro.Id) flag = false;
					}
					if (flag)
					{
						item.StonePid = allPro.Id;
						break;
					}
				}
				if (!IsRunning) return;
				Log($"已检测到炉石(Pid={item.StonePid})运行中");

				//停止战网进程
				if (NeedCloseBattle || ForceCloseBattle)
				{
					Log("停止战网中...");
					while (BattleNetProcess.Length != 0 && IsRunning)
					{
						foreach (Process process in BattleNetProcess)
						{
							try
							{
								process.Kill();
								Delay(1000);
								Log($"检测到战网(Pid={process.Id})已停止");
							}
							catch { }
						}
					}
					if (!IsRunning) return;
				}

				//停止战网更新进程
				Log("停止战网更新进程中...");
				Process[] pros = BattleNetUpdateAgentProcess;
				if (pros != null && pros.Length > 0)
				{
					foreach (Process pro in pros)
					{
						pro.Kill();
						Delay(1000);
						Log($"检测到战网更新进程(Pid={pro.Id})已停止");
					}
				}
			}
			catch { }
		}

		//启动炉石兄弟
		private void StartHearthbuddy(AccountCheckedItem item)
		{
			if (!IsRunning) return;

			Log("准备启动炉石兄弟");
			try
			{
				//启动炉石兄弟
				Log($"未检测到炉石兄弟，启动炉石兄弟中...");
				Process process = new Process();
				process.StartInfo.UseShellExecute = false;
				process.StartInfo.FileName = HearthbuddyPath;
				process.StartInfo.Arguments = "--autostart --config:Default";
				if (item.StonePid != 0)
				{
					process.StartInfo.Arguments += " --pid:" + item.StonePid.ToString();
				}
				if (!string.IsNullOrEmpty(item.Deck))
				{
					process.StartInfo.Arguments += " --deck:" + item.Deck;
				}
				process.StartInfo.Arguments += " --behavior:" + item.Behavior.ToString();
				process.StartInfo.Arguments += " --rule:" + item.Rule.ToString();
				process.StartInfo.Arguments += " --os:" + (SystemVersion==0?"10":"7");
				process.Start();
				Log("已经启动炉石兄弟，是否成功，听天由命~");
			}
			catch { }
		}

		//窗口加载
		private void Window_Loaded(object sender, RoutedEventArgs e)
		{
			Title = MyTitlt;
			Log("请先完整配置一次炉石兄弟运行成功后，再使用中控");
			Log("同时必须先在中控里面配置账号的模式、卡组、策略");

			//日志路径
			string text = Path.Combine(BaseDirectory, "Logs");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string text1 = Path.Combine(BaseDirectory, "Settings/Default");
			if (!Directory.Exists(text1))
			{
				Directory.CreateDirectory(text1);
			}
			string text2 = Path.Combine(BaseDirectory,
				"Routines/DefaultRoutine/Silverfish/UltimateLogs");
			if (!Directory.Exists(text2))
			{
				Directory.CreateDirectory(text2);
			}

			//加载xml配置文件
			XmlConfigUtil util = new XmlConfigUtil("Settings/Default/HearthHelper.xml");
			BattleNetPath = util.Read("BattleNetPath");
			HearthstonePath = util.Read("HearthstonePath");
			HearthbuddyPath = util.Read("HearthbuddyPath");
			PushPlusToken = util.Read("PushPlusToken");

			//读取数据
			try { BNHSInterval = int.Parse(util.Read("BNHSInterval")); }
			catch
			{
				BNHSInterval = DefaultBNHSInterval;
				Log($"读取数据错误，恢复默认值={DefaultBNHSInterval}");
			}
			try { HSHBInterval = int.Parse(util.Read("HSHBInterval")); }
			catch
			{
				HSHBInterval = DefaultHSHBInterval;
				Log($"读取数据错误，恢复默认值={DefaultHSHBInterval}");
			}
			try { CheckInterval = int.Parse(util.Read("CheckInterval")); }
			catch
			{
				CheckInterval = DefaultCheckInterval;
				Log($"读取数据错误，恢复默认值={DefaultCheckInterval}");
			}
			try { RebootCntMax = int.Parse(util.Read("RebootCntMax")); }
			catch
			{
				RebootCntMax = DefaultRebootCntMax;
				Log($"读取数据错误，恢复默认值={DefaultRebootCntMax}");
			}
			try { PushNormalInterval = int.Parse(util.Read("PushNormalInterval")); }
			catch
			{
				PushNormalInterval = DefaultPushNormalInterval;
				Log($"读取数据错误，恢复默认值={DefaultPushNormalInterval}");
			}
			try { NeedCloseBattle = bool.Parse(util.Read("NeedCloseBattle")); }
			catch
			{
				NeedCloseBattle = true;
				Log($"读取数据错误，恢复默认值={true}");
			}
			try { NeedMultStone = bool.Parse(util.Read("NeedMultStone")); }
			catch
			{
				NeedMultStone = false;
				Log($"读取数据错误，恢复默认值={false}");
			}
			try { NeedPushMessage = bool.Parse(util.Read("NeedPushMessage")); }
			catch
			{
				NeedPushMessage = true;
				Log($"读取数据错误，恢复默认值={true}");
			}

			try { NeedPushNormal = bool.Parse(util.Read("NeedPushNormal")); }
			catch
			{
				NeedPushNormal = false;
				Log($"读取数据错误，恢复默认值={false}");
			}
			try { SystemVersion = int.Parse(util.Read("SystemVersion")); }
			catch
			{
				SystemVersion = DefaultSystemVersion;
				Log($"读取数据错误，恢复默认值={DefaultSystemVersion}");
			}

			//自动获取路径
			if (string.IsNullOrEmpty(BattleNetPath))
			{
				BattleNetPath = AutoGetBattleNetPath();
			}
			if (string.IsNullOrEmpty(HearthstonePath))
			{
				HearthstonePath = AutoGetHearthstonePath();
			}
			if (string.IsNullOrEmpty(HearthbuddyPath))
			{
				HearthbuddyPath = AutoGetHearthBuddyPath();
			}

			//读取战网账号配置
			string path = GetBattleConfig();
			try
			{
				using (StreamReader file = File.OpenText(path))
				{
					using (JsonTextReader reader = new JsonTextReader(file))
					{
						//读取
						JObject jsonObj = (JObject)JToken.ReadFrom(reader);
						string saved = (string)jsonObj["Client"]["SavedAccountNames"];
						string[] sArray = Regex.Split(saved, ",", RegexOptions.IgnoreCase);
						foreach (string account in sArray)
						{
							AccountList.Add(new AccountCheckedItem(false, account));
						}
						AccountListBox.ItemsSource = AccountList;
						file.Close();
					}
				}
			}
			catch (Exception ex)
			{
				Log(ex.Message);
				Log("无法读取战网用户数据");
			}

			//读取用户配置数据
			foreach (AccountCheckedItem accountCheckedItem in AccountList)
			{
				try
				{
					accountCheckedItem.Selected = bool.Parse(util.Read(new string[]
					{
						"BattleNetAccount",
						"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
						"Selected"
					}));
					accountCheckedItem.Rule = int.Parse(util.Read(new string[]
					{
						"BattleNetAccount",
						"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
						"Rule"
					}));
					accountCheckedItem.Deck = util.Read(new string[]
					{
						"BattleNetAccount",
						"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
						"Deck"
					});
					accountCheckedItem.Behavior = int.Parse(util.Read(new string[]
					{
						"BattleNetAccount",
						"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
						"Behavior"
					}));
					accountCheckedItem.StartTime = int.Parse(util.Read(new string[]
					{
						"BattleNetAccount",
						"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
						"StartTime"
					}));
					accountCheckedItem.EndTime = int.Parse(util.Read(new string[]
					{
						"BattleNetAccount",
						"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
						"EndTime"
					}));
				}
				catch
				{
					Log($"读取账号{accountCheckedItem.EmailShow}数据错误");
				}
			}

			//循环
			TimerTick.Interval = 1000;
			TimerTick.Tick += Tick;
			TimerMonitor.Interval = 1000;
			TimerMonitor.Tick += MyMonitor;
			TimerMonitor.Start();
		}

		//修改登录账号
		private void ChangeLoginAccount(string email)
		{
			string path = GetBattleConfig();
			try
			{
				//账号重新排序
				string newInfo = "";
				newInfo += email;
				foreach (AccountCheckedItem account in AccountList)
				{
					if (account.Email != email) newInfo += "," + account.Email;
				}

				//写入新信息
				string json = File.ReadAllText(path);
				dynamic jsonObj = JsonConvert.DeserializeObject(json);
				jsonObj["Client"]["SavedAccountNames"] = newInfo;
				string output = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
				File.WriteAllText(path, output);
				Log($"修改当前战网用户为{HideUtil.ReplaceWithSpecialChar(email)}成功");
			}
			catch (Exception ex)
			{
				Log(ex.Message);
				Log("无法读取战网用户数据");
			}
		}

		//判断当前账号是否满足挂机时间
		private bool IsAccountInRunTime(AccountCheckedItem account)
		{
			int currHour = DateTime.Now.Hour;
			if ((account.StartTime < account.EndTime &&
				currHour >= account.StartTime &&
				currHour < account.EndTime) ||
				(account.StartTime > account.EndTime &&
				!(currHour >= account.EndTime &&
				currHour < account.StartTime)))
			{
				return true;
			}
			return false;
		}

		//获取选中且满足挂机时间的第一个账号
		private bool GetFirstInRunTimeAccount(out AccountCheckedItem account)
		{
			AccountCheckedItem old = CurrRunningAccount;
			foreach (AccountCheckedItem accountCheckedItem in AccountList)
			{
				if (accountCheckedItem.Selected && IsRunning &&
					IsAccountInRunTime(accountCheckedItem))
				{
					account = accountCheckedItem;
					if (old.Email.Length>0 &&
						!string.Equals(old.Email, accountCheckedItem.Email))
					{
						ForceCloseBattle = true;
						if (NeedPushMessage)
						{
							string result;
							PushStone.PostMessage(PushPlusToken, old.Email,
								account.Email, TodayRebootCnt, RebootCntMax,
								PushStone.MSG_TYPE.MSG_CHANGE, out result);
							Log(result);
						}
					}
					Log($"账号{account.EmailShow}满足挂机时间(" +
						$"{CurrRunningAccount.StartTime}-{CurrRunningAccount.EndTime})");
					return true;
				}
			}
			account = new AccountCheckedItem(false, "");
			return false;
		}

		//重启大法
		private void Reboot()
		{
			try
			{
				using (Mutex mut = new Mutex(false, "HearthHelp"))
				{
					try
					{
						mut.WaitOne();

						//获取当前时间
						LastDateTime=GetFileCurrTime(true);

						//停止炉石和战网
						StopHearthstone();
						Delay(5000);

						//切换账号
						ChangeLoginAccount(CurrRunningAccount.Email);
						Delay(500);

						//开始启动炉石
						ForceCloseBattle = false;
						StartHearthstone(CurrRunningAccount);
						Log($"{HSHBInterval}秒后启动炉石兄弟");
						Delay(1000 * HSHBInterval);

						//开始启动炉石兄弟
						StartHearthbuddy(CurrRunningAccount);
						Delay(30 * 1000);

						//启动完成
						if (IsRunning)
						{
							CurrRunningAccount.Running = true;
							StartOrStopButton.Content =
								"停止运行（当前挂机账号" + CurrRunningAccount.EmailShow + "）";
							Log("预计已全部启动成功，开始循环检测");
						}
					}
					finally
					{
						mut.ReleaseMutex();
					}
				}
			}
			catch (Exception ex)
			{
				Log(ex.ToString());
			}
		}

		//监控程序
		private void MyMonitor(object sender, EventArgs e)
		{
			//判断时间，重置TodayRebootCnt
			TimeSpan nowDt = DateTime.Now.TimeOfDay;
			TimeSpan workStart = DateTime.Parse("00:00:00").TimeOfDay;
			TimeSpan workStop = DateTime.Parse("00:00:05").TimeOfDay;
			if (nowDt > workStart && nowDt < workStop)
			{
				Log($"当前时间0点0分，重启次数重置为0");
				TodayRebootCnt = -1;
				TimerMonitor.Stop();
				Delay(1000*6);
				TimerMonitor.Interval = 1000;
				TimerMonitor.Start();
			}
			if (TodayRebootCnt==-1)
			{
				TodayRebootCnt = 0;
				TodayRebootCntStr = TodayRebootCnt.ToString() + "/";
				if (!IsRunning)
				{
					if (NeedPushMessage)
					{
						string result;
						PushStone.PostMessage(PushPlusToken, "",
							CurrRunningAccount.Email, TodayRebootCnt, RebootCntMax,
							PushStone.MSG_TYPE.MSG_START, out result);
						Log(result);
					}
					Log($"一日之计在于晨，兄弟中控自动开始运行");
					StartRun();
				}
			}
			if (IsRunning) LogTextBox.ScrollToEnd();
		}

		//获取文件最新写时间
		private DateTime GetFileCurrTime(bool bFirst)
		{
			DirectoryInfo directoryInfo = new DirectoryInfo(
				Path.Combine(BaseDirectory,
				"Routines/DefaultRoutine/Silverfish/UltimateLogs"));
			DateTime dateTime = default(DateTime);
			if (bFirst) dateTime = DateTime.Now;
			else 
			{
				foreach (FileInfo fileInfo in directoryInfo.GetFiles("*.txt"))
				{
					if (DateTime.Compare(fileInfo.LastWriteTime, dateTime) > 0)
					{
						dateTime = fileInfo.LastWriteTime;
					}
				}
			}
			Log($"日志最新时间={dateTime.ToLongTimeString()}");
			return dateTime;
		}

		//循环处理
		private void Tick(object sender, EventArgs e)
		{
			TimerTick.Interval = 60000 * CheckInterval;

			//有账号在运行
			if (CurrRunningAccount.Running)
			{
				if (!IsAccountInRunTime(CurrRunningAccount))
				{
					Log($"账号{CurrRunningAccount.EmailShow}未在挂机时间内(" +
						$"{CurrRunningAccount.StartTime}-{CurrRunningAccount.EndTime})");
					StopHearthstone();
					TimerTick.Interval = 1000 * 10;
					CurrRunningAccount.Running = false;
					return;
				}
			}
			else
			{
				if (GetFirstInRunTimeAccount(out CurrRunningAccount))
				{
					Log("未检测到目标账号挂机中，准备启动挂机流程...");
					Reboot();
				}
				else
				{
					StopHearthstone();
					Log($"当前时间没有账号需要挂机，{CheckInterval}分钟后再次检测");
				}
				return;
			}

			//定时检测日志
			DirectoryInfo directoryInfo = new DirectoryInfo(
				Path.Combine(BaseDirectory,
				"Routines/DefaultRoutine/Silverfish/UltimateLogs"));
			DateTime dateTime = GetFileCurrTime(false);
			int inter = DateTime.Compare(dateTime, LastDateTime);
			if (inter>0)
			{
				Log($"日志上次时间={LastDateTime.ToLongTimeString()}，炉石兄弟运行正常");
				TimeSpan ts1 = new TimeSpan(LastDateTime.Ticks);
				TimeSpan ts2 = new TimeSpan(dateTime.Ticks);
				TimeSpan ts3 = ts2.Subtract(ts1);
				if (ts3.TotalSeconds<(CheckInterval*60))
				{
					TimerTick.Interval = (int)(1000 * ts3.TotalSeconds);
				}
				Log($"{TimerTick.Interval/1000/60}分{TimerTick.Interval/1000%60}秒后再次检测~");
				if (NeedPushMessage && NeedPushNormal &&
					(DateTime.Now.ToBinary()/1000/10000-LastPushNormalDateTime)>
					PushNormalInterval * 3600)
				{
					LastPushNormalDateTime = DateTime.Now.ToBinary()/1000/10000-60;
					string result;
					PushStone.PostMessage(PushPlusToken, "",
						CurrRunningAccount.Email, TodayRebootCnt, RebootCntMax, 
						PushStone.MSG_TYPE.MSG_NORMAL, out result);
					Log(result);
				}
				LastDateTime = dateTime;
				return;
			}

			//日志异常
			Log($"日志上次时间={LastDateTime.ToLongTimeString()}，准备使用重启大法...");
			TodayRebootCnt++;
			TodayRebootCntStr = TodayRebootCnt.ToString() + "/";
			if (TodayRebootCnt > RebootCntMax)
			{
				Log($"今日重启次数已达最大值{RebootCntMax}，兄弟中控自动停止运行");
				if (NeedPushMessage)
				{
					string result;
					PushStone.PostMessage(PushPlusToken, "",
						CurrRunningAccount.Email, RebootCntMax, RebootCntMax,
						PushStone.MSG_TYPE.MSG_STOP, out result);
					Log(result);
				}
				StopHearthstone();
				StopRun();
				return;
			}
			else 
			{
				if (NeedPushMessage)
				{
					string result;
					PushStone.PostMessage(PushPlusToken, "",
						CurrRunningAccount.Email, TodayRebootCnt, RebootCntMax,
						PushStone.MSG_TYPE.MSG_REBOOT, out result);
					Log(result);
				}
				Reboot();
				return;
			}
		}

		//战网路径选择处理
		private void SelectBattleNetFileButton_Click(object sender, RoutedEventArgs e)
		{
			string text = SelectExeFile("Battle.net Launcher.exe|*.exe");
			if (!string.IsNullOrEmpty(text))
			{
				BattleNetPath = text;
				Log("战网路径配置成功：");
				Log(text);
			}
		}

		//补丁路径选择处理
		private void SelectHearthstoneFileButton_Click(object sender, RoutedEventArgs e)
		{
			string text = SelectExeFile("Assembly-CSharp.dll|*.dll");
			if (!string.IsNullOrEmpty(text))
			{
				HearthstonePath = text;
				Log("补丁路径配置成功：");
				Log(text);
			}
		}

		//兄弟路径选择处理
		private void SelectHearthbuddyFileButton_Click(object sender, RoutedEventArgs e)
		{
			string text = SelectExeFile("Hearthbuddy.exe|*.exe");
			if (!string.IsNullOrEmpty(text))
			{
				HearthbuddyPath = text;
				Log("兄弟路径配置成功：");
				Log(text);
			}
		}

		//打炉石补丁
		private void PatchStoneButton1_Click(object sender, RoutedEventArgs e)
		{
			if (PatchStone.PatchHearthStone(HearthstonePath, 0)) Log("打窗口最小化补丁成功");
			else Log("打窗口最小化补丁失败，请先关闭炉石客户端");
		}
		private void PatchStoneButton2_Click(object sender, RoutedEventArgs e)
		{
			if (PatchStone.PatchHearthStone(HearthstonePath, 1)) Log("打去除广告补丁成功");
			else Log("打去除广告补丁失败，请先关闭炉石客户端");
		}
		private void PatchStoneButton3_Click(object sender, RoutedEventArgs e)
		{
			if (PatchStone.PatchHearthStone(HearthstonePath, 2)) Log("打去除特有开门补丁成功");
			else Log("打去除特有开门补丁失败，请先关闭炉石客户端");
		}
		private void PatchStoneButton4_Click(object sender, RoutedEventArgs e)
		{
			if (PatchStone.PatchHearthStone(HearthstonePath, 3)) Log("打去除金卡特效补丁成功");
			else Log("打去除金卡特效补丁失败，请先关闭炉石客户端");
		}

		//进入官网获取Token
		private void GetPushTokenButton_Click(object sender, RoutedEventArgs e)
		{
			Process.Start("https://www.pushplus.plus/push1.html");
			Log("IE浏览器扫码后无法跳页面时，请更换其他浏览器重新扫描二维码");
		}

		//测试消息推送
		private void TestPushMessageButton_Click(object sender, RoutedEventArgs e)
		{
			string result;
			PushStone.PostMessage(PushPlusToken,
				"123456789@qq.com",
				"987654321@qq.com", 5, 30,
				PushStone.MSG_TYPE.MSG_TEST, out result);
			Log(result);
			System.Windows.MessageBox.Show(
				result.ToString(), "", MessageBoxButton.OK);
		}

		//数字输入
		private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
		{
			Regex regex = new Regex("[^0-9]+");
			e.Handled = regex.IsMatch(e.Text);
		}
		private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = false;
			e.Handled = true;
		}

		//账号配置
		private void ConfigAccountButton_Click(object sender, RoutedEventArgs e)
		{
			System.Windows.Controls.Button button = sender as System.Windows.Controls.Button;
			if (button != null)
			{
				AccountCheckedItem accountCheckedItem = button.Tag as AccountCheckedItem;
				int index = AccountList.IndexOf(accountCheckedItem);
				AccountConfigPopup accountConfigPopup = new AccountConfigPopup(ref accountCheckedItem);
				accountConfigPopup.Left = Left + (Width - accountConfigPopup.Width) / 2.0;
				accountConfigPopup.Top = Top + (Height - accountConfigPopup.Height) / 2.0;
				accountConfigPopup.ShowDialog();
				AccountList[index] = accountCheckedItem;
			}
		}

		//窗口关闭
		private void Window_Closed(object sender, EventArgs e)
		{
			XmlConfigUtil unil = new XmlConfigUtil("Settings/Default/HearthHelper.xml");
			unil.Write(BattleNetPath,"BattleNetPath");
			unil.Write(HearthstonePath,"HearthstonePath");
			unil.Write(HearthbuddyPath,"HearthbuddyPath");
			unil.Write(PushPlusToken, "PushPlusToken");
			unil.Write(BNHSInterval.ToString(),"BNHSInterval");
			unil.Write(HSHBInterval.ToString(),"HSHBInterval");
			unil.Write(CheckInterval.ToString(),"CheckInterval");
			unil.Write(RebootCntMax.ToString(),"RebootCntMax");
			unil.Write(SystemVersion.ToString(),"SystemVersion");
			unil.Write(PushNormalInterval.ToString(),"PushNormalInterval");
			unil.Write(NeedCloseBattle.ToString(),"NeedCloseBattle");
			unil.Write(NeedMultStone.ToString(),"NeedMultStone");
			unil.Write(NeedPushMessage.ToString(),"NeedPushMessage");
			unil.Write(NeedPushNormal.ToString(),"NeedPushNormal");
			foreach (AccountCheckedItem accountCheckedItem in AccountList)
			{
				unil.Write(accountCheckedItem.Selected.ToString(), new string[]
				{
					"BattleNetAccount",
					"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
					"Selected"
				});
				unil.Write(accountCheckedItem.Rule.ToString(), new string[]
				{
					"BattleNetAccount",
					"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
					"Rule"
				});
				unil.Write(accountCheckedItem.Behavior.ToString(), new string[]
				{
					"BattleNetAccount",
					"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
					"Behavior"
				});
				unil.Write(accountCheckedItem.Deck, new string[]
				{
					"BattleNetAccount",
					"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
					"Deck"
				});
				unil.Write(accountCheckedItem.StartTime.ToString(), new string[]
				{
					"BattleNetAccount",
					"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
					"StartTime"
				});
				unil.Write(accountCheckedItem.EndTime.ToString(), new string[]
				{
					"BattleNetAccount",
					"HASH" + accountCheckedItem.Email.GetHashCode().ToString(),
					"EndTime"
				});
			}

			//日志路径
			string text = Path.Combine(BaseDirectory, "Logs");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string text1 = Path.Combine(BaseDirectory, "Settings/Default");
			if (!Directory.Exists(text1))
			{
				Directory.CreateDirectory(text1);
			}
			string text2 = Path.Combine(BaseDirectory,
				"Routines/DefaultRoutine/Silverfish/UltimateLogs");
			if (!Directory.Exists(text2))
			{
				Directory.CreateDirectory(text2);
			}
			using (StreamWriter streamWriter = new StreamWriter(
				Path.Combine(text, string.Format(
				"HearthHelper_{0}.log", DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss"))),
				true, Encoding.UTF8))
			{
				streamWriter.Write(LogTextBox.Text);
			}
			Environment.Exit(0);
		}

		//开始运行
		private void StartRun()
		{
			if (!IsRunning)
			{
				//配置错误
				bool bError = false;
				if (!File.Exists(BattleNetPath))
				{
					bError = true;
					Log("战网路径配置错误");
				}
				if (!File.Exists(HearthbuddyPath))
				{
					bError = true;
					Log("兄弟路径配置错误");
				}
				if (!bError && BaseDirectory != Directory.GetParent(HearthbuddyPath).FullName + "\\")
				{
					bError = true;
					Log("本程序未放置在兄弟根目录");
					Log("当前目录：" + BaseDirectory);
					Log("所配置兄弟目录：" + Directory.GetParent(HearthbuddyPath).FullName + "\\");
				}
				if (bError) return;

				//开始运行
				IsRunning = true;
				StartOrStopButton.Content = "停止运行";
				SelectBattleNetFileButton.IsEnabled = false;
				SelectHearthstoneFileButton.IsEnabled = false;
				SelectHearthbuddyFileButton.IsEnabled = false;
				PatchStoneButton1.IsEnabled = false;
				PatchStoneButton2.IsEnabled = false;
				PatchStoneButton3.IsEnabled = false;
				PatchStoneButton4.IsEnabled = false;
				GetPushTokenButton.IsEnabled = false;
				TestPushMessageButton.IsEnabled = false;
				AccountListBox.IsEnabled = false;
				BattleNetPathTextBox.IsEnabled = false;
				HearthstonePathTextBox.IsEnabled = false;
				HearthbuddyPathTextBox.IsEnabled = false;
				PushPlusTokenTextBox.IsEnabled = false;
				BNHSIntervalTextBox.IsEnabled = false;
				HSHBIntervalTextBox.IsEnabled = false;
				CheckIntervalTextBox.IsEnabled = false;
				RebootMaxCntTextBox.IsEnabled = false;
				SystemVersionComboBox.IsEnabled = false;
				PushNormalIntervalTextBox.IsEnabled = false;
				NeedCloseBattleCheckBox.IsEnabled = false;
				NeedMultStoneCheckBox.IsEnabled = false;
				NeedPushMessageCheckBox.IsEnabled = false;
				NeedPushNormalCheckBox.IsEnabled = false;
				Log($"配置成功，兄弟中控开始运行...");
				Log("多开模式会一直在等待其他中控操作完成，请稍等...");
				TimerTick.Interval = 1000;
				TimerTick.Start();
			}
		}

		private void StopRun()
		{
			if (IsRunning)
			{
				//停止运行
				IsRunning = false;
				CurrRunningAccount.Running = false;
				StartOrStopButton.Content = "开始运行（兄弟最新版本链接 https://gitee.com/UniverseString）";
				SelectBattleNetFileButton.IsEnabled = true;
				SelectHearthstoneFileButton.IsEnabled = true;
				SelectHearthbuddyFileButton.IsEnabled = true;
				PatchStoneButton1.IsEnabled = true;
				PatchStoneButton2.IsEnabled = true;
				PatchStoneButton3.IsEnabled = true;
				PatchStoneButton4.IsEnabled = true;
				GetPushTokenButton.IsEnabled = true;
				TestPushMessageButton.IsEnabled = true;
				AccountListBox.IsEnabled = true;
				BattleNetPathTextBox.IsEnabled = true;
				HearthstonePathTextBox.IsEnabled = true;
				HearthbuddyPathTextBox.IsEnabled = true;
				PushPlusTokenTextBox.IsEnabled = true;
				BNHSIntervalTextBox.IsEnabled = true;
				HSHBIntervalTextBox.IsEnabled = true;
				CheckIntervalTextBox.IsEnabled = true;
				RebootMaxCntTextBox.IsEnabled = true;
				SystemVersionComboBox.IsEnabled = true;
				PushNormalIntervalTextBox.IsEnabled = true;
				NeedCloseBattleCheckBox.IsEnabled = true;
				NeedMultStoneCheckBox.IsEnabled = true;
				NeedPushMessageCheckBox.IsEnabled = true;
				NeedPushNormalCheckBox.IsEnabled = true;
				TimerTick.Interval = 1000;
				TimerTick.Stop();
				Log($"兄弟中控已停止");
			}
		}

		//开始或停止
		private void StartOrStopButton_Click(object sender, RoutedEventArgs e)
		{
			if (IsRunning) StopRun();
			else StartRun();
		}
	}
}

